import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import { Message, Modal } from "@arco-design/web-vue";
import { useUserStore } from "@/stores";
import { getToken } from "@/utils/auth";
import router from "@/router";

interface IRequestConfig extends AxiosRequestConfig{
  headers?: AxiosRequestConfig['headers'];
}




const http: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 30 * 1000
});


http.interceptors.request.use(
  (config: IRequestConfig) => {
    const isFormData = config.data instanceof FormData;
    const isToken = (config.headers || {}).isToken === false;
    isFormData && (config.headers!["Content-Type"] = "multipart/form-data");
    if (getToken() && !isToken) {
      config.headers!["Authorization"] = `Bearer ${getToken()}`;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

const errorCode = [20003, 20002, 20001]
http.interceptors.response.use(
  (res: AxiosResponse) => {
    if (["blob", "arraybuffer"].includes(res.request.responseType)) {
      return res;
    }
    const { msg, code } = res.data;
    if (code === 401) {
      Modal.confirm({
        title: "提示",
        content: "登录已过期，请重新登录",
        okText: "重新登录",
        cancelText: "取消",
        onOk: () => {
            router.replace("/login");
          // useUserStore().logout().then(()=>{
          //   router.replace("/login");
          // }).catch(err=>{
          //   Message.error(err.message);
          // })
        }
      });
      return Promise.reject(new Error("token失效"));
    }else if(code === 500){
        Message.error(msg);
      return Promise.reject(new Error(msg));
    }else if(errorCode.includes(code)){
        return Promise.resolve(res);
    } else if(code !== 200){
        Message.error(msg || "服务器异常！");
        return Promise.reject(new Error(msg || "服务器异常！"));
    }else {
      return Promise.resolve(res);
    }
  },
  error => {
    Message.clear();
    const response = Object.assign({}, error.response);
    response && Message.error( "系统异常, 请检查网络或联系管理员！");
    return Promise.reject(new Error("系统异常, 请检查网络或联系管理员！"));
  }
);

const request = <T = unknown>(config: AxiosRequestConfig): Promise<ApiRes<T>> => {
  return new Promise((resolve, reject) => {
    http
      .request<T>(config)
      .then((res: AxiosResponse) => resolve(res.data))
      .catch((err: { message: string }) => reject(err));
  });
};

const get = <T = any>(url: string, params?: object, config?: AxiosRequestConfig): Promise<ApiRes<T>> => {
  return request({
    method: "get",
    url,
    params,
    ...config
  });
};

const deleteMethod = <T = any>(url: string, params?: object, config?: AxiosRequestConfig): Promise<ApiRes<T>> => {
    return request({
        method: "delete",
        url,
        params,
        ...config
    });
};

const post = <T = any>(url: string, params?: object, config?: AxiosRequestConfig): Promise<ApiRes<T>> => {
  return request({
    method: "post",
    url,
    data: params,
    ...config
  });
};

const put = <T = any>(url: string, params?: object, config?: AxiosRequestConfig): Promise<ApiRes<T>> => {
  return request({
    method: "put",
    url,
    data: params,
    ...config
  });
};




export default { get, post, put, deleteMethod };
